home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / dev / gg / ncurses-5.3.lha / ncurses-5.3 / menu / m_global.c < prev    next >
C/C++ Source or Header  |  2002-10-24  |  16KB  |  493 lines

  1. /****************************************************************************
  2.  * Copyright (c) 1998,2000 Free Software Foundation, Inc.                   *
  3.  *                                                                          *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a  *
  5.  * copy of this software and associated documentation files (the            *
  6.  * "Software"), to deal in the Software without restriction, including      *
  7.  * without limitation the rights to use, copy, modify, merge, publish,      *
  8.  * distribute, distribute with modifications, sublicense, and/or sell       *
  9.  * copies of the Software, and to permit persons to whom the Software is    *
  10.  * furnished to do so, subject to the following conditions:                 *
  11.  *                                                                          *
  12.  * The above copyright notice and this permission notice shall be included  *
  13.  * in all copies or substantial portions of the Software.                   *
  14.  *                                                                          *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
  16.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
  18.  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
  21.  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
  22.  *                                                                          *
  23.  * Except as contained in this notice, the name(s) of the above copyright   *
  24.  * holders shall not be used in advertising or otherwise to promote the     *
  25.  * sale, use or other dealings in this Software without prior written       *
  26.  * authorization.                                                           *
  27.  ****************************************************************************/
  28.  
  29. /****************************************************************************
  30.  *   Author:  Juergen Pfeifer, 1995,1997                                    *
  31.  *   Contact: http://www.familiepfeifer.de/Contact.aspx?Lang=en             *
  32.  ****************************************************************************/
  33.  
  34. /***************************************************************************
  35. * Module m_global                                                          *
  36. * Globally used internal routines and the default menu and item structures *
  37. ***************************************************************************/
  38.  
  39. #include "menu.priv.h"
  40.  
  41. MODULE_ID("$Id: m_global.c,v 1.14 2002/07/06 15:22:16 juergen Exp $")
  42.  
  43. static char mark[] = "-";
  44.  
  45. NCURSES_EXPORT_VAR(MENU) _nc_Default_Menu = {
  46.   16,                  /* Nr. of chars high */
  47.   1,                  /* Nr. of chars wide */
  48.   16,                  /* Nr. of items high */
  49.   1,                      /* Nr. of items wide */
  50.   16,                  /* Nr. of formatted items high */
  51.   1,                  /* Nr. of formatted items wide */
  52.   16,                  /* Nr. of items high (actual) */
  53.   0,                  /* length of widest name */
  54.   0,                  /* length of widest description */
  55.   1,                  /* length of mark */
  56.   1,                  /* length of one item */
  57.   1,                              /* Spacing for descriptor */ 
  58.   1,                              /* Spacing for columns */
  59.   1,                              /* Spacing for rows */
  60.   (char *)0,              /* buffer used to store match chars */
  61.   0,                  /* Index into pattern buffer */
  62.   (WINDOW *)0,              /* Window containing entire menu */
  63.   (WINDOW *)0,              /* Portion of menu displayed */
  64.   (WINDOW *)0,              /* User's window */
  65.   (WINDOW *)0,              /* User's subwindow */
  66.   (ITEM **)0,              /* List of items */
  67.   0,                  /* Total Nr. of items in menu */
  68.   (ITEM *)0,              /* Current item */
  69.   0,                  /* Top row of menu */
  70.   (chtype)A_REVERSE,          /* Attribute for selection */
  71.   (chtype)A_NORMAL,          /* Attribute for nonselection */
  72.   (chtype)A_UNDERLINE,          /* Attribute for inactive */    
  73.   ' ',                /* Pad character */
  74.   (Menu_Hook)0,              /* Menu init */
  75.   (Menu_Hook)0,              /* Menu term */
  76.   (Menu_Hook)0,              /* Item init */
  77.   (Menu_Hook)0,              /* Item term */
  78.   (void *)0,              /* userptr */
  79.   mark,                  /* mark */
  80.   ALL_MENU_OPTS,                  /* options */
  81.   0                      /* status */        
  82. };
  83.  
  84. NCURSES_EXPORT_VAR(ITEM) _nc_Default_Item = {
  85.   { (char *)0, 0 },          /* name */
  86.   { (char *)0, 0 },          /* description */
  87.   (MENU *)0,                  /* Pointer to parent menu */
  88.   (char *)0,              /* Userpointer */
  89.   ALL_ITEM_OPTS,          /* options */
  90.   0,                  /* Item Nr. */
  91.   0,                  /* y */
  92.   0,                  /* x */
  93.   FALSE,              /* value */
  94.   (ITEM *)0,                  /* left */
  95.   (ITEM *)0,                  /* right */
  96.   (ITEM *)0,                  /* up */
  97.   (ITEM *)0                  /* down */
  98.   };
  99.  
  100. /*---------------------------------------------------------------------------
  101. |   Facility      :  libnmenu  
  102. |   Function      :  static void ComputeMaximum_NameDesc_Lenths(MENU *menu)
  103. |   
  104. |   Description   :  Calculates the maximum name and description lengths
  105. |                    of the items connected to the menu
  106. |
  107. |   Return Values :  -
  108. +--------------------------------------------------------------------------*/
  109. INLINE static void ComputeMaximum_NameDesc_Lengths(MENU * menu)
  110. {
  111.   unsigned MaximumNameLength        = 0;
  112.   unsigned MaximumDescriptionLength = 0;
  113.   ITEM **items;
  114.   
  115.   assert(menu && menu->items);
  116.   for( items = menu->items; *items ; items++ )
  117.     {
  118.       if (items[0]->name.length > MaximumNameLength )
  119.     MaximumNameLength  = items[0]->name.length;
  120.       
  121.       if (items[0]->description.length > MaximumDescriptionLength)
  122.     MaximumDescriptionLength = items[0]->description.length;
  123.     }
  124.   
  125.   menu->namelen = MaximumNameLength;
  126.   menu->desclen = MaximumDescriptionLength;
  127. }
  128.  
  129. /*---------------------------------------------------------------------------
  130. |   Facility      :  libnmenu  
  131. |   Function      :  static void ResetConnectionInfo(MENU *, ITEM **)
  132. |   
  133. |   Description   :  Reset all informations in the menu and the items in
  134. |                    the item array that indicates a connection
  135. |
  136. |   Return Values :  -
  137. +--------------------------------------------------------------------------*/
  138. INLINE static void ResetConnectionInfo(MENU *menu, ITEM **items)
  139. {
  140.   ITEM **item;
  141.   
  142.   assert(menu && items);
  143.   for(item=items; *item; item++)
  144.     {
  145.       (*item)->index = 0;
  146.       (*item)->imenu = (MENU *)0;        
  147.     }
  148.   if (menu->pattern)
  149.     free(menu->pattern);
  150.   menu->pattern = (char *)0;
  151.   menu->pindex  = 0;
  152.   menu->items   = (ITEM **)0;
  153.   menu->nitems  = 0;
  154. }
  155.  
  156. /*---------------------------------------------------------------------------
  157. |   Facility      :  libnmenu  
  158. |   Function      :  bool _nc_Connect_Items(MENU *menu, ITEM **items)
  159. |
  160. |   Description   :  Connect the items in the item array to the menu.
  161. |                    Decorate all the items with a number and a backward
  162. |                    pointer to the menu.
  163. |
  164. |   Return Values :  TRUE       - successfull connection
  165. |                    FALSE      - connection failed
  166. +--------------------------------------------------------------------------*/
  167. NCURSES_EXPORT(bool)
  168. _nc_Connect_Items (MENU *menu, ITEM **items)
  169. {
  170.   ITEM **item;
  171.   unsigned int ItemCount = 0;
  172.   
  173.   if ( menu && items )
  174.     {    
  175.       for(item=items; *item ; item++)
  176.     {
  177.       if ( (*item)->imenu )
  178.         {
  179.           /* if a item is already connected, reject connection */
  180.           break;
  181.         }
  182.     }
  183.       if (! (*item) )        
  184.     /* we reached the end, so there was no connected item */
  185.     {
  186.       for(item=items; *item ; item++)
  187.         {
  188.           if (menu->opt & O_ONEVALUE)
  189.         {
  190.           (*item)->value = FALSE;
  191.         }
  192.           (*item)->index = ItemCount++;
  193.           (*item)->imenu = menu;
  194.         }            
  195.     }
  196.     }
  197.   else
  198.     return(FALSE);
  199.   
  200.   if (ItemCount != 0)
  201.     {
  202.       menu->items  = items;
  203.       menu->nitems = ItemCount;
  204.       ComputeMaximum_NameDesc_Lengths(menu);
  205.       if ( (menu->pattern = (char *)malloc( (unsigned)(1 + menu->namelen))) )
  206.     {
  207.       Reset_Pattern(menu);    
  208.       set_menu_format(menu,menu->frows,menu->fcols);
  209.       menu->curitem = *items;
  210.       menu->toprow = 0;
  211.       return(TRUE);
  212.     }
  213.     }
  214.   
  215.   /* If we fall through to this point, we have to reset all items connection 
  216.      and inform about a reject connection */
  217.   ResetConnectionInfo( menu, items );
  218.   return(FALSE);
  219. }
  220.  
  221. /*---------------------------------------------------------------------------
  222. |   Facility      :  libnmenu  
  223. |   Function      :  void _nc_Disconnect_Items(MENU *menu)
  224. |   
  225. |   Description   :  Disconnect the menus item array from the menu
  226. |
  227. |   Return Values :  -
  228. +--------------------------------------------------------------------------*/
  229. NCURSES_EXPORT(void)
  230. _nc_Disconnect_Items (MENU * menu)
  231. {
  232.   if (menu && menu->items)
  233.     ResetConnectionInfo( menu, menu->items );
  234. }
  235.  
  236. /*---------------------------------------------------------------------------
  237. |   Facility      :  libnmenu  
  238. |   Function      :  void _nc_Calculate_Item_Length_and_Width(MENU *menu)
  239. |   
  240. |   Description   :  Calculate the length of an item and the width of the
  241. |                    whole menu.
  242. |
  243. |   Return Values :  -
  244. +--------------------------------------------------------------------------*/
  245. NCURSES_EXPORT(void)
  246. _nc_Calculate_Item_Length_and_Width (MENU * menu)
  247. {
  248.   int l;
  249.   
  250.   assert(menu);
  251.  
  252.   menu->height  = 1 + menu->spc_rows * (menu->arows - 1);
  253.  
  254.   l = menu->namelen + menu->marklen;
  255.   if ( (menu->opt & O_SHOWDESC) && (menu->desclen > 0) )
  256.     l += (menu->desclen + menu->spc_desc);
  257.   
  258.   menu->itemlen = l;
  259.   l *= menu->cols;
  260.   l += (menu->cols-1)*menu->spc_cols; /* for the padding between the columns */
  261.   menu->width = l;
  262. }  
  263.  
  264. /*---------------------------------------------------------------------------
  265. |   Facility      :  libnmenu  
  266. |   Function      :  void _nc_Link_Item(MENU *menu)
  267. |   
  268. |   Description   :  Statically calculate for every item its four neighbours.
  269. |                    This depends on the orientation of the menu. This
  270. |                    static aproach simplifies navigation in the menu a lot.
  271. |
  272. |   Return Values :  -
  273. +--------------------------------------------------------------------------*/
  274. NCURSES_EXPORT(void)
  275. _nc_Link_Items (MENU * menu)
  276. {
  277.   if (menu && menu->items && *(menu->items))
  278.     {
  279.       int i,j;
  280.       ITEM *item;
  281.       int Number_Of_Items = menu->nitems;
  282.       int col = 0, row = 0;
  283.       int Last_in_Row;
  284.       int Last_in_Column;
  285.       bool cycle = (menu->opt & O_NONCYCLIC) ? FALSE : TRUE;
  286.       
  287.       menu->status &= ~_LINK_NEEDED;
  288.       
  289.       if (menu->opt & O_ROWMAJOR)
  290.     {
  291.       int Number_Of_Columns = menu->cols;
  292.       
  293.       for(i=0; i < Number_Of_Items; i++)
  294.         {
  295.           item = menu->items[i];
  296.           
  297.           Last_in_Row = row * Number_Of_Columns + (Number_Of_Columns-1);
  298.           
  299.           item->left  = (col) ? 
  300.         /* if we are not in the leftmost column, we can use the
  301.            predecessor in the items array */
  302.         menu->items[i-1] :
  303.           (cycle ? menu->items[(Last_in_Row>=Number_Of_Items) ? 
  304.                        Number_Of_Items-1:
  305.                        Last_in_Row] : 
  306.            (ITEM *)0 );
  307.           
  308.           item->right = (  (col < (Number_Of_Columns-1)) && 
  309.                  ((i+1) < Number_Of_Items) 
  310.                  ) ? 
  311.                    menu->items[i+1] :
  312.                  ( cycle ? menu->items[row * Number_Of_Columns] : 
  313.                   (ITEM *)0
  314.                   );
  315.           
  316.           Last_in_Column = (menu->rows-1) * Number_Of_Columns + col;
  317.           
  318.           item->up    = (row) ? menu->items[i-Number_Of_Columns] :
  319.         (cycle ? menu->items[(Last_in_Column>=Number_Of_Items) ?
  320.                      Number_Of_Items-1 : 
  321.                      Last_in_Column] : 
  322.          (ITEM *)0);
  323.           
  324.           item->down  = ( (i+Number_Of_Columns) < Number_Of_Items ) 
  325.         ? 
  326.           menu->items[i + Number_Of_Columns] :
  327.             (cycle ? menu->items[(row+1)<menu->rows ?
  328.                      Number_Of_Items-1:col] : 
  329.              (ITEM *)0);
  330.           item->x = col;
  331.           item->y = row;
  332.           if ( ++col == Number_Of_Columns )
  333.         {
  334.           row++;
  335.           col = 0;
  336.         }
  337.         }
  338.     }
  339.       else
  340.     {
  341.       int Number_Of_Rows = menu->rows;
  342.       
  343.       for(j=0; j<Number_Of_Items; j++)
  344.         {
  345.           item = menu->items[i=(col * Number_Of_Rows + row)];
  346.           
  347.           Last_in_Column = (menu->cols-1) * Number_Of_Rows + row;
  348.           
  349.           item->left  = (col) ? 
  350.         menu->items[i - Number_Of_Rows] :
  351.           (cycle ? (Last_in_Column >= Number_Of_Items ) ? 
  352.            menu->items[Last_in_Column-Number_Of_Rows] : 
  353.            menu->items[Last_in_Column] : 
  354.            (ITEM *)0 );
  355.           
  356.           item->right = ((i + Number_Of_Rows) <Number_Of_Items) 
  357.         ? 
  358.           menu->items[i + Number_Of_Rows] :
  359.             (cycle ? menu->items[row] : (ITEM *)0);
  360.           
  361.           Last_in_Row = col * Number_Of_Rows + (Number_Of_Rows - 1);
  362.           
  363.           item->up    = (row) ? 
  364.         menu->items[i-1] :
  365.           (cycle ?
  366.            menu->items[(Last_in_Row>=Number_Of_Items) ? 
  367.                    Number_Of_Items-1:
  368.                    Last_in_Row] :
  369.            (ITEM *)0);
  370.           
  371.           item->down  = (row < (Number_Of_Rows-1)) 
  372.         ? 
  373.           (menu->items[((i+1)<Number_Of_Items) ? 
  374.                    i+1 :
  375.                    (col-1)*Number_Of_Rows + row + 1]) :
  376.                  (cycle ?
  377.                   menu->items[col * Number_Of_Rows] :
  378.                   (ITEM *)0
  379.                   );
  380.           
  381.           item->x = col;
  382.           item->y = row;
  383.           if ( (++row) == Number_Of_Rows )
  384.         {
  385.           col++;
  386.           row = 0;
  387.         }
  388.         }
  389.     }
  390.     }
  391. }
  392.  
  393. /*---------------------------------------------------------------------------
  394. |   Facility      :  libnmenu  
  395. |   Function      :  void _nc_Show_Menu(const MENU *menu)
  396. |   
  397. |   Description   :  Update the window that is associated with the menu
  398. |
  399. |   Return Values :  -
  400. +--------------------------------------------------------------------------*/
  401. NCURSES_EXPORT(void)
  402. _nc_Show_Menu (const MENU *menu)
  403. {
  404.   WINDOW *win;
  405.   int maxy, maxx;
  406.   
  407.   assert(menu);
  408.   if ( (menu->status & _POSTED) && !(menu->status & _IN_DRIVER) )
  409.     {
  410.       /* adjust the internal subwindow to start on the current top */
  411.       assert(menu->sub);
  412.       mvderwin(menu->sub,menu->spc_rows * menu->toprow,0);
  413.       win = Get_Menu_Window(menu);
  414.       
  415.       maxy = getmaxy(win);
  416.       maxx = getmaxx(win);     
  417.       
  418.       if (menu->height < maxy) 
  419.     maxy = menu->height;
  420.       if (menu->width < maxx) 
  421.     maxx = menu->width;
  422.       
  423.       copywin(menu->sub,win,0,0,0,0,maxy-1,maxx-1,0);
  424.       pos_menu_cursor(menu);
  425.     }    
  426. }    
  427.  
  428. /*---------------------------------------------------------------------------
  429. |   Facility      :  libnmenu  
  430. |   Function      :  void _nc_New_TopRow_and_CurrentItem(
  431. |                            MENU *menu, 
  432. |                            int new_toprow, 
  433. |                            ITEM *new_current_item)
  434. |   
  435. |   Description   :  Redisplay the menu so that the given row becomes the
  436. |                    top row and the given item becomes the new current
  437. |                    item.
  438. |
  439. |   Return Values :  -
  440. +--------------------------------------------------------------------------*/
  441. NCURSES_EXPORT(void)
  442. _nc_New_TopRow_and_CurrentItem
  443. (MENU *menu, int new_toprow, ITEM *new_current_item)
  444. {
  445.   ITEM *cur_item;
  446.   bool mterm_called = FALSE;
  447.   bool iterm_called = FALSE;
  448.   
  449.   assert(menu);
  450.   if (menu->status & _POSTED)
  451.     {
  452.       if (new_current_item != menu->curitem)
  453.     {
  454.       Call_Hook(menu,itemterm);
  455.       iterm_called = TRUE;
  456.     }
  457.       if (new_toprow != menu->toprow)
  458.     {
  459.       Call_Hook(menu,menuterm);
  460.       mterm_called = TRUE;
  461.     }            
  462.       
  463.       cur_item  = menu->curitem;
  464.       assert(cur_item);
  465.       menu->toprow  = new_toprow;
  466.       menu->curitem = new_current_item;            
  467.       
  468.       if (mterm_called)
  469.     {
  470.       Call_Hook(menu,menuinit);
  471.     }
  472.       if (iterm_called)
  473.     {
  474.       /* this means, move from the old current_item to the new one... */
  475.       Move_To_Current_Item( menu, cur_item );
  476.       Call_Hook(menu,iteminit);
  477.     }
  478.       if (mterm_called || iterm_called)
  479.     {
  480.       _nc_Show_Menu(menu);
  481.     }
  482.       else
  483.     pos_menu_cursor(menu);
  484.     }
  485.   else
  486.     { /* if we are not posted, this is quite simple */
  487.       menu->toprow  = new_toprow;
  488.       menu->curitem = new_current_item;
  489.     }
  490. }
  491.  
  492. /* m_global.c ends here */
  493.